package com.qf.file.controller;


import com.qf.base.controller.BaseController;
import com.qf.base.dto.file.*;
import com.qf.base.result.R;
import com.qf.base.utils.AsyncBatchCallUtil;
import com.qf.base.utils.Base64Util;
import com.qf.base.utils.ImageUtil;
import com.qf.base.utils.SnowFlakeUtil;
import com.qf.file.client.PushClient;
import com.qf.file.model.GifWork;
import com.qf.file.service.GifService;
import com.qf.file.utils.AlibabaOSSUtil;
import com.qf.file.utils.QFCodeUtil;
import org.apache.tomcat.util.codec.binary.Base64;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;

/**
 * @author 30909
 */
@RestController
@RequestMapping("qf/file")
public class FileController extends BaseController {

    @Resource
    private SnowFlakeUtil snowFlakeUtil;

    @Resource
    private GifService gifService;

    @Resource
    private PushClient pushClient;
    /**
     * 临时目录
     */
    public static final String FILE_PATH = "C:\\TEMP";


    /**
     * 上传图片的接口
     */
    @PostMapping("img")
    public R uploadImage(@RequestBody ImgDTO imgDTO) {
        String base64 = imgDTO.getBase64();
        //雪花算法
        String fileName = snowFlakeUtil.nextId() + ".jgp";
        //这里有方案一 但是.... 当时老师讲的好像是有两次 io 操作
        //目标是上传到阿里云OOS服务器
        //要有文件
        //目前Base64，因此把base64变成文件
        // File file = Base64Util.base64ToFile(base64, FILE_PATH + File.separator + fileName);
        //  String url = AlibabaOSSUtil.uploadFile(FILE_PATH, file);


        //方案二
        byte[] bytes = Base64.decodeBase64(base64);
        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
        String uri = AlibabaOSSUtil.uploadFile(fileName, bais);
        return R.ok("上传成功").setResult("url", uri);


    }

    /**
     * 上传视频的接口
     */
    @PostMapping("mp4")
    public R uploadMP4(MultipartFile file) {

        //生成一个文件名
        String fileName = snowFlakeUtil.nextId() + ".mp4";
        InputStream is = null;

        try {
            is = file.getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        //把流交给阿里云服务器
        String url = AlibabaOSSUtil.uploadFile(fileName, is);
        return R.ok("上传成功").setResult("url", url);
    }

    /**
     * 这是一个上传MP4 文件自动生成gif 预览与jpf封面的接口
     * 这是一个高耗时接口。
     * 采用异步接口的设计：与同步设计相对应，同步童虎设计就扣被请求了以后
     * 秒级响应处理结果。而异步设计就饿被请求以后，立即返回任务已经开始执行
     * 后台慢慢处理，然后再有一个查询任务的接口，你可以查询之前的后台任务时候执行文笔
     */

    /**
     * 基于推送设计的异步接口
     */
    @PostMapping("mp4ForGifAndJpg")
    public R uploadMp4File(MultipartFile file) {
        //生成文件名
        String fileName = snowFlakeUtil.nextId() + ".mp4";
        //实例话临时目录
        File targetFile = new File(FILE_PATH + File.separator + file);
        //写入到文件中
        try {
            file.transferTo(targetFile);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //获取文件的url
        String url = AlibabaOSSUtil.getUrl(fileName);
        //添加到数据库
        gifService.addGifWork(url);
        AsyncBatchCallUtil.execute(() -> gifService.createGif(targetFile, fileName, url));
        return R.ok("正在积极处理").setResult("url", url);
    }


    /**
     * 查询 gif 与jpg生成情况的方法
     */
    @PostMapping("search")
    public R SearchWork(@RequestBody PathDTO pathDTO) {

        //这个url 现在不可以用
        String url = pathDTO.getUrl();
        //查询数据
        GifWork gifWork = gifService.selectByVideoUrl(url);
        return R.ok("查询成功").setResult(gifWork);
    }

    /**
     *图片上传
     * 放缩图片
     * @param zoomDTO
     * @return
     */
    @PostMapping("zoom")
    public R uploadZoomImage(@RequestBody ZoomDTO zoomDTO) {
        String base64 = zoomDTO.getBase64();
        int width = zoomDTO.getWidth();
        int height = zoomDTO.getHeight();

        //base64->bufferedImage
        BufferedImage bufferedImage = Base64Util.base64ToImage(base64);
        //bufferedImage缩放
        bufferedImage = ImageUtil.zoom(bufferedImage, width, height);

        String url = uploadAliyun(bufferedImage);
        return R.ok("放缩成功").setResult("url", url);

    }

    /**
     * 图片上传
     * 放缩图片
     * RequestHeader 向服务器发送一个请求头
     */
    @PostMapping("zoomForBase64")
    public  R uploadZoomImageBase(@RequestBody ZoomDTO zoomDTO,@RequestHeader("token") String token){
        String base64 = zoomDTO.getBase64();
        int width = zoomDTO.getWidth();
        int height = zoomDTO.getHeight();

        //base64 -> bufferedImage =
        BufferedImage bufferedImage = Base64Util.base64ToImage(base64);
        //图片缩放的方法
        bufferedImage = ImageUtil.zoom(bufferedImage,width,height);
        return  R.ok("缩放成功").setResult("base64",Base64Util.image2Base64(bufferedImage));
    }

    /**
     * 添加水印的方法
     */
    @PostMapping("markOn")
    public R markOn(@RequestBody MarkDTO markDTO) {
        String base64 = markDTO.getBase64();
        String mark = markDTO.getMark();

        BufferedImage bufferedImage = Base64Util.base64ToImage(base64);
        bufferedImage = ImageUtil.markOn(bufferedImage, mark);
        String url = uploadAliyun(bufferedImage);
        return R.ok("添加水印成功").setResult("url", url);


    }




    /**
     *  生成二维码的接口
     */
    @PostMapping("qrCode")
    public R qfCode(@RequestBody QFCodeDTO qfCodeDTO){
        String content = qfCodeDTO.getContent();
        Integer width = qfCodeDTO.getWidth();
        Integer height = qfCodeDTO.getHeight();
        //前端的颜色 是 #ffffff 的形式
        String codeColorStr = qfCodeDTO.getCodeColor().replace("#", "");
        String bgColorStr = qfCodeDTO.getBgColor().replace("#", "");
        //十六进制转 int
        int codeColor = Integer.parseInt(codeColorStr, 16);
        int bgColor = Integer.parseInt(bgColorStr, 16);
        //拼接进透明度
        codeColor=codeColor|(0xff<<24);
        bgColor = bgColor|(0xff<<24);
        BufferedImage bufferedImage = QFCodeUtil.qfEncode(content,codeColor,bgColor,width,height);
        String url = uploadAliyun(bufferedImage);
        return R.ok("二维码生成成功").setResult("url",url);

    }



    @PostMapping("mp4ForGifAndJpg")
    public R uploadMP4FileForPushMag(MultipartFile file){
        return null;
    }

    /**
     *    放到阿里云上
     * @param bufferedImage
     * @return  返回阿里云的存储地址
     */
    private String uploadAliyun(BufferedImage bufferedImage) {

        String base64 = Base64Util.image2Base64(bufferedImage);
        byte[] bytes = Base64.decodeBase64(base64);
        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
        String fileName = snowFlakeUtil.nextId() + ".jpg";
        String url = AlibabaOSSUtil.uploadFile(fileName, bais);
        return url;
    }


}
